package utils.common;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Created by franklin on 6/5/2017.
 */

public class HttpTools {

    public static void main(String[] args) {

        HttpTools ht = new HttpTools("http://www.baidu.com", "GET");
        if (ht.sendRequest()) {
            System.out.println(ht.getResponseBody());
            System.out.println(ht.getResponseCode());
        }
    }

    private String apiUrl;
    private HttpClient client = null;
    private StringEntity entity = null;
    private HttpResponse response = null;
    private String method = "";
    private String path = "";
    private String param = "";
    private String fragment;
    private int code;
    private String body;
    private String requestBody;
    private Map<String, String> headers = new HashMap<String, String>();

    private StringBuffer sb = new StringBuffer();

    public HttpTools(String apiUrl, String method) {

        this.apiUrl = apiUrl;
        this.method = method;
    }

    public String path(String path) {

        this.path = path.trim();
        return this.path;
    }

    public void param(String key, String value) {

        if (!StringUtils.isBlank(this.param)) {
            this.param += "&";
        }
        this.param += key.trim() + "=" + value.trim();
    }

    public void fragment(String info) {

        sb.append(info);
    }

    public void headers(String key, String value) {

        this.headers.put(key.trim(), value.trim());
    }

    public void body(String requestBody) {

        this.requestBody = requestBody.trim();
    }

    public boolean sendRequest() {

        boolean flag = false;
        try {
//            client = new DefaultHttpClient();
//            client = new HttpClient();
            client = HttpClients.createDefault();

            client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 600000);
            client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 600000);

            if (!StringUtils.isBlank(path)) {
                apiUrl += path;
            }

            if (!StringUtils.isBlank(param)) {
                apiUrl += "?" + param;
            }

            if (!StringUtils.isBlank(fragment)) {
                apiUrl += "#" + fragment;
            }

            if (!StringUtils.isBlank(requestBody)) {
                entity = new StringEntity(requestBody);
            }
            if (method.equalsIgnoreCase("GET")) {
                HttpGet get = new HttpGet(apiUrl);
                if (!this.headers.isEmpty()) {
                    for (Map.Entry<String, String> header : headers.entrySet()) {
                        get.addHeader(header.getKey(), header.getValue());
                    }
                }
                response = client.execute(get);
            } else if (method.equalsIgnoreCase("POST")) {
                HttpPost post = new HttpPost(apiUrl);
                if (!this.headers.isEmpty()) {
                    for (Map.Entry<String, String> header : headers.entrySet()) {
                        post.addHeader(header.getKey(), header.getValue());
                    }
                }
                post.setEntity(entity);
                response = client.execute(post);
            } else if (method.equalsIgnoreCase("PUT")) {
                HttpPut put = new HttpPut(apiUrl);
                if (!this.headers.isEmpty()) {
                    for (Map.Entry<String, String> header : headers.entrySet()) {
                        put.addHeader(header.getKey(), header.getValue());
                    }
                }
                put.setEntity(entity);
                response = client.execute(put);
            } else if (method.equalsIgnoreCase("DELETE")) {
                HttpDelete delete = new HttpDelete(apiUrl);
                if (!this.headers.isEmpty()) {
                    for (Map.Entry<String, String> header : headers.entrySet()) {
                        delete.addHeader(header.getKey(), header.getValue());
                    }
                }
                response = client.execute(delete);

            }

            HttpEntity entity = response.getEntity();
            body = EntityUtils.toString(entity);
        } catch (Exception e) {
        }

        int code = response.getStatusLine().getStatusCode();
        this.code = code;
        if (response != null)
            flag = true;

        client.getConnectionManager().shutdown();

        return flag;
    }

    public String getResponseBody() {

        System.out.println("The response body is " + body);
        return body;
    }

    public int getResponseCode() {

        System.out.println("The response code is " + code);
        return code;
    }

    public static String getHttpResponse4Get() {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String url = "http://www.tmall.com/test.do?id=123";
//        GetMethod httpGet = new GetMethod(url);
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("content-type", "text/html; charset=gbk");
        httpGet.getParams().setParameter("http.socket.timeout", 20000);

        try {
            // 设置成了默认的恢复策略，在发生异常时候将自动重试3次，在这里你也可以设置成自定义的恢复策略
//            httpGet.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
            CloseableHttpResponse resp = httpclient.execute(httpGet);
            if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                System.out.println("httpGet(\"" + url + "\") failed: \n"+ resp.getStatusLine());
                return null;
            }

            return resp.getEntity().toString();
        } catch (Exception e) {
            System.out.println("httpGet(\"" + url + "\") failed: \n" + e.getMessage());
            return null;
        } finally {
            httpGet.releaseConnection();
            httpclient = null;
        }

    }

    public static String getHttpResponse4Post() {
        HttpClient client = HttpClients.createMinimal();

        try {
            client = new DefaultHttpClient();
            HttpPost request = new HttpPost("http://www.tmall.com/test.do");
            // 使用NameValuePair来保存要传递的Post参数
            List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
            // 添加要传递的参数
            postParameters.add(new BasicNameValuePair("id", "12345"));
            postParameters.add(new BasicNameValuePair("username", "dave"));
            // 实例化UrlEncodedFormEntity对象
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
                    postParameters);
            // 使用HttpPost对象来设置UrlEncodedFormEntity的Entity
            request.setEntity(formEntity);
            HttpResponse response = client.execute(request);

            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String s = EntityUtils.toString(response.getEntity(), "utf-8");
                System.out.println(s);
                System.out.println("请求正常，结束http请求");
                return s;
            }
        } catch (Exception e) {
            System.out.println("请求发生异常，异常信息抛出");
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return " ";
    }

}
